const ab3 = (b)=>{
    //  0 <= b <= 8
    let a = new Uint8Array(3);
    // b & 011 = b & 3
    a[2] = ((b & 3 ) << 6) & (b << 3) & b; 
    // b & 011 = b & 3
    a[1] = ((b & 1 ) << 7) & (b << 4) & (b << 1) & (b >> 2); 
    // b & 011 = b & 3
    a[0] = (b << 5) & (b << 2) & ((b & 3 ) << 1); 
    return a;
}

const A = [];
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++) {
    if(i === j) continue;
    A.push([ab3(i),ab3(j)]);
} }

const B = [];
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++) {
for (let k = 0; k < 8; k++) {
    if(i === j || j === k || i === k) continue;
    B.push([ab3(i),ab3(j),ab3(k)]);
} } }
    
const eq = (a,b)=> (a[0] === b[0] && a[1] === b[1] && a[2] === b[2])
const bf = (f,a,b)=> {
    let c = new Uint8Array(3);
    let d = new Uint8Array(3);
    let e = new Uint8Array(3);

    c.set(a);
    d.set(b);

    e[0] = f(c[0],d[0]);
    e[1] = f(c[1],d[1]);
    e[2] = f(c[2],d[2]);

    return e;
}
const ck = (f1, f2, p1, n1, p2, n2) => eq(bf(f1,p1, n1), p2) && eq(bf(f2,p1, n1), n2);

const FS = [
    (p, n) => p & n,
    (p, n) => ~p & n,
    (p, n) => p & ~n,
    (p, n) => ~p & ~n,
    (p, n) => p | n,
    (p, n) => ~p | n,
    (p, n) => p | ~n,
    (p, n) => ~p | ~n,
    (p, n) => p ^ n,
    (p, n) => ~p ^ n,
    (p, n) => p ^ ~n,
    (p, n) => ~p ^ ~n,
]

let x, y, z, a, b, c;

/*
x:'0',y:'1',z:'_',a:'0',b:'1',c:'2'
(x,a) -> (x,a)
(x,b) -> (y,a)
(x,c) -> (x,b)
(y,a) -> (y,b)
(y,b) -> (x,c)
(y,c) -> (y,c)
(z,a) -> (z,a)
(z,b) -> (x,b)
(z,c) -> (z,c)
*/

(() => {

for (const p of A) {
for (const n of B) {
    // [x, y, z] = p;
    [x, y] = p;
    [a, b, c] = n;

    let rd = [
        [x, a, x, a], [x, b, y, a], [x, c, x, b],
        [y, a, y, b], [y, b, x, c], [y, c, y, c],
        // [z, a, z, a], [z, b, z, b], [z, c, z, c],
    ]

    let count = 0;
    for (const f1 of FS) {
    for (const f2 of FS) {
        if (rd.some(k => !ck(f1, f2, k[0], k[1], k[2], k[3]))) break;
        count++;
    }
    }
    if(count === 6){
        console.log(`x:${x.toString(2)},y:${y.toString(2)},` +
        `a:${a.toString(2)},b:${b.toString(2)},c:${c.toString(2)}`);
        console.log(`f1:${f1.toString()}\nf2:${f2.toString()}`)
    }
}
}

})();